Instead of using the C++-linker, use the D compiler to link LDC2 and LDMD#1368
Conversation
| // In driver/ldmd.cpp | ||
| extern(C++) int cppmain(int argc, char **argv); | ||
|
|
||
| /+ Having a main() in D-source solves a few issues with building/linking with D compiler. |
There was a problem hiding this comment.
Could you just mention DMD/Windows here explicitly?
|
Thanks for continuing this rather cumbersome job! |
|
I need to beat this thing |
|
I am not sure if it was a good idea to compile all D source in one go. It makes compilation significantly slower when you just change one cpp file... |
If you are worried about .cpp files, we can always split up the C and D parts of the compilation process and use DMD just for linking (in case you are not doing this already). Regarding .d files, DMD compiles all at once and it seems to work out fine for them. |
Yes, but it's just a little slower when only one file changed. |
2569ad2 to
9702b11
Compare
| } No newline at end of file | ||
| } | ||
|
|
||
| // In driver/main.cpp or driver/ldmd.cpp |
|
Thanks! |
|
I wonder if compiling all D source at once improves performance when built with LDC. LDC becomes much faster (tested on Weka source) when built with |
|
|
Be sure to also use |
|
Green on AppVeyor and Travis. |
|
Don't merge yet. make install does not mark ldc2 and ldmd2 as executables. Working on a fix. |
|
Results from a "quick" test on some code that takes a while to compile (CMAKE_BUILD_TYPE=Release): |
|
Install of executables is fixed. Please merge! |
|
Let's do this! It's definitely a step forward, and we better figure out any potentially remaining issues as soon as possible. |
|
Hmm the Windows x86 build fails, because it cannot find a pdb file. For x86, DMD uses its own linker which probably cannot generate pdb's? |
|
Hmm, I thought DMD supports PDB, but maybe only if the full source is in D, and not for COFF objects produced by the MSVC++ compiler. Anyway, I only include the PDB to enable easier troubleshooting for people experimenting with CI builds. We can also just omit it for the x86 build if we don't find a better solution. Edit: The x86 jobs actually fail in |
|
@kinke Could be a missing flag? Edit: good that you checked the log again. |
|
I am going to try and reproduce this on Windows, by following the appveyor.yml file for 32bit compilation. |
|
This PR fixes issue #1379 |
…LDMD. This removes the need for the CMake logic to figure out what linker flags to pass the C++linker to link D code (50 lines of flaky cmake script).
|
@klickverbot: merging this just killed our 32-bit MSVC build. Please don't discard AppVeyor issues. |
|
I'll look into a fix. The issue seems to be Edit: |
|
This snippet demonstrates the problem: enum MANTISSA_LSB = 0;
enum MANTISSA_MSB = 1;
long lrint(real x)
{
long result;
// Rounding limit when casting from real(double) to ulong.
enum real OF = 4.50359962737049600000E15L;
uint* vi = cast(uint*)(&x);
// Find the exponent and sign
uint msb = vi[MANTISSA_MSB];
uint lsb = vi[MANTISSA_LSB];
int exp = ((msb >> 20) & 0x7ff) - 0x3ff;
int sign = msb >> 31;
msb &= 0xfffff;
msb |= 0x100000;
if (exp < 63)
{
if (exp >= 52)
result = (cast(long) msb << (exp - 20)) | (lsb << (exp - 52));
else
{
// Adjust x and check result.
real j = sign ? -OF : OF;
x = (j + x) - j;
msb = vi[MANTISSA_MSB];
lsb = vi[MANTISSA_LSB];
exp = ((msb >> 20) & 0x7ff) - 0x3ff;
msb &= 0xfffff;
msb |= 0x100000;
if (exp < 0)
result = 0;
else if (exp < 20)
result = cast(long) msb >> (20 - exp);
else if (exp == 20)
result = cast(long) msb;
else
result = (cast(long) msb << (exp - 20)) | (lsb >> (52 - exp));
}
}
else
{
// It is left implementation defined when the number is too large.
return cast(long) x;
}
return sign ? -result : result;
}
void main()
{
import core.stdc.stdio;
printf("actual = %lld, expected = %lld\n", lrint(int.max - 0.5), 2147483646L);
printf("actual = %lld, expected = %lld\n", lrint(int.max + 0.5), 2147483648L);
printf("actual = %lld, expected = %lld\n", lrint(int.min - 0.5), -2147483648L);
printf("actual = %lld, expected = %lld\n", lrint(int.min + 0.5), -2147483648L);
}=> The output is correct if |
|
I've just compared the IR for above |
|
Sorry, I had missed the AppVeyor failures; feel free to revert. |
|
I can't make heads or tails of the failure, though. Linking is done using MSVC |
vs. Apparently |
|
I seem to be a bit on the slow side today (hence also the merge in the first place), but do we have a clue yet as to why this happens? Is this due to |
|
No idea. Maybe we just got lucky and found a lurking bug which hasn't shown up until now. Sadly with that DMD-linked build, I don't have any PDBs so I cannot debug what's going on in LDC. I'll continue investigating. |
|
@kinke So this PR means we lose a lot of debugging convenience on Windows? :( |
|
Okay so it's not |
|
Oh wait - when using DMD to compile the front-end, the front-end uses 80-bit compile-time reals. LDC's glue layer for MSVC targets only uses 64-bit Edit: It's really time for a proper |
When DMD builds the executable, is there any difference between |
|
I'm 99.9% sure that this is because we miss most and not just a few ddmd |
|
But the AppVeyor build was always using DMD, right? |
Sure; OMF vs. COFF and optlink vs. MSVC. |
|
I'm also convinced this is the reason why the
Yep, LDC 0.17 crashes when building our current front-end. ;) |
Nope, same issue. :/ |
|
... but db9af1d (built with DMD) is at least able to build the front-end without crashing, and the resulting LDC is able to build druntime+Phobos (debug+release). Tested with 32-bit MSVC and by manually adding |
|
All commits of #1317 (built with DMD) gets rid of this issue, i.e., |
It seems that runtime is not rebuilt if ldc2 was rebuild. Did a dependency on ldc2 get dropped? |
I think that was a different, mysterious reason. The |
Noticed it too. I checked the dependencies, and they look correct but obviously aren't. Edit: working on a cmake fix now. |
|
Probably totally unrelated but while building LDC master today on Pi to make sure this PR works in that environment, hit a malloc assertion during unittest build: I don't have core dump enabled so nothing to point to. Malloc assertions often point to memory corruption. Nothing to do now, just leaving behind a clue. Second time worked. |
This removes the need for the CMake logic to figure out what linker flags to pass the C++linker to link D code (50 lines of flaky cmake script).
Continuation from #1361